package com.yeyi.ytest.java8.stream;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;  

/**
 * https://blog.csdn.net/lengguoxing/article/details/78414996
 * Java8 Stream的分组，分区
 */
public class StreamGroupByTest {
	public static void main(String[] args) {  
        User user1 = new User("zhangsan", 60, 20, new Sex(0));  
        User user2 = new User("lisi", 80, 23, new Sex(1));  
        User user3 = new User("zhangsan", 80, 24, new Sex(1));  
        User user4 = new User(null, 50, 24, new Sex(0)); 

        // 名字为空要特殊处理
        List<User> userList = Arrays.asList(user1, user2, user3, user4);  
        userList.stream().forEach(e -> {
        	if(e.getName()==null) {
        		e.setName("");
        	}
        });
        //按照名字分组  
        Map<String, List<User>> nameMap = userList.stream().collect(Collectors.groupingBy(User::getName));  
        System.out.println("nameMap = " + nameMap);  
        
        /**
         * https://www.cnblogs.com/yangweiqiang/p/6934671.html
         * List -> Map
         * 需要注意的是：
         * toMap 如果集合对象有重复的key，会报错Duplicate key ....
         *  apple1,apple12的id都为1。
         *  可以用 (k1,k2)->k1 来设置，如果有重复的key,则保留key1,舍弃key2
         */
        Map<Integer, User> nameMapp = userList.stream().collect(Collectors.toMap(User::getScore, a -> a,(k1,k2)->k1));
        System.out.println("nameMapp = " + nameMapp);
  
        //按照分数分组  
        Map<Integer, List<User>> scoreMap = userList.stream().collect(Collectors.groupingBy(User::getScore));
        System.out.println("scoreMap = " + scoreMap);
        
        // 复杂类型分组https://stackoverflow.com/questions/19254884/collectors-tomap-keymapper-more-succinct-expression
        Map<Integer, List<User>> scoreMapSuccinct = userList.stream().collect(Collectors.groupingBy(
                new Function<User, Integer>() { 
                    @Override
                    public Integer apply(User p) { return p.getSex().getS(); } 
                }
        ));
        System.out.println("scoreMapSuccinct = " + scoreMapSuccinct);
  
        //按照名字分组，并求出个数  
        Map<String, Long> nameMap2 = userList.stream().collect(Collectors.groupingBy(User::getName, Collectors.counting()));  
        System.out.println("nameMap2 = " + nameMap2);  
  
        //按照名字分组，分数平局值  
        Map<String, Double> nameMap3 = userList.stream().collect(Collectors.groupingBy(User::getName, Collectors.averagingDouble(User::getScore)));  
        System.out.println("nameMap3 = " + nameMap3);  
  
        /**分区：分区是分组的一种特殊情况，分组可以分成多组，分区只分成2组**/  
        //及格的人  
        Map<Boolean, List<User>> map4 = userList.stream().collect(Collectors.partitioningBy(user -> user.getScore() >= 60));  
        System.out.println("map4 = " + map4);  
    }  
}

class Sex{
    int s;

    public Sex(int s) {
        super();
        this.s = s;
    }

    public int getS() {
        return s;
    }

    public void setS(int s) {
        this.s = s;
    }
}

class User{  
    private String name;  
    private int score;  
    private int age;
    private Sex sex;
    
    public User(String name, int score, int age, Sex sex) {
        super();
        this.name = name;
        this.score = score;
        this.age = age;
        this.sex = sex;
    }
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public int getScore() {  
        return score;  
    }  
    public void setScore(int score) {  
        this.score = score;  
    }  
    public int getAge() {  
        return age;  
    }  
    public void setAge(int age) {  
        this.age = age;  
    }
    public Sex getSex() {
        return sex;
    }
    public void setSex(Sex sex) {
        this.sex = sex;
    }  
}  